package com.hnair.grpc.example.interceptor;

import com.hnair.grpc.example.utils.GrpcUtil;
import io.grpc.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public abstract class BaseServerInterceptor implements ServerInterceptor {

    private static final Logger log = LoggerFactory.getLogger(BaseServerInterceptor.class);

    public static final String IP_PATTERN = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}";

    /* (non-Javadoc)
     * @see io.grpc.ServerInterceptor#interceptCall(io.grpc.ServerCall, io.grpc.Metadata, io.grpc.ServerCallHandler)
     */
    @Override
    public abstract <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next);

    public void addHeader(Metadata headers, String key, String value) {
        headers.put(Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER), value);
    }

    public boolean containsHeader(Metadata headers, String key) {
        return headers.containsKey(Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER));
    }

    public String getHeader(Metadata headers, String key) {
        return headers.get(Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER));
    }

    public <ReqT, RespT> ServerCall.Listener<ReqT> close(ServerCall<ReqT, RespT> call, Metadata headers, Status status, String description) {
        addHeader(headers, GrpcUtil.IS_CLOSE, "yes");
        call.close(status, new Metadata());
        return new ServerCall.Listener<ReqT>() {};
    }

    public <ReqT, RespT> String getRemoteIP(ServerCall<ReqT, RespT> call, Metadata headers) {
        String clientIP = headers.get(Metadata.Key.of(GrpcUtil.X_FORWARDED_FOR, Metadata.ASCII_STRING_MARSHALLER));
        log.debug("getRemoteIp:{}",clientIP);
        if (null == clientIP || !clientIP.matches(IP_PATTERN)) {
            clientIP = GrpcUtil.getClientIP(call);
            log.debug("GrpcUtil.getClientIP:{}",clientIP);
        }
        return clientIP;
    }



}
